package com.ruoyi.web.controller.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.ruoyi.common.annotation.ApiLog;
import com.ruoyi.common.core.page.ResponseResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.OrderStatusEnum;
import com.ruoyi.common.exception.BusiException;
import com.ruoyi.common.utils.file.AliOss;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.system.ali.AliPayVo;
import com.ruoyi.system.biz.BizOrderService;
import com.ruoyi.system.domain.Bank;
import com.ruoyi.system.domain.Order;
import com.ruoyi.system.dto.ApiNotifyDto;
import com.ruoyi.system.dto.ApiOrderReceiveAddDto;
import com.ruoyi.system.dto.OrderAddDto;
import com.ruoyi.system.service.CashHistoryService;
import com.ruoyi.system.service.GoodsService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.OrderService;
import com.ruoyi.system.websocket.WebSocketServer1;
import com.ruoyi.web.controller.app.AppController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Date;
import java.util.Map;

@Api(tags = "开放接口---代收")
@RestController
@RequestMapping("/api/order")
public class OrderReceiveController extends AppController {
    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
    @Resource
    private OrderService orderService;
    @Resource
    private CashHistoryService cashHistoryService;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private WebSocketServer1 webSocketServer;

    @Resource
    private BizOrderService bizOrderService;

    @Resource
    private ISysConfigService configService;

    @ApiOperation(value = "发送消息")
    @RequestMapping("/sendByUserId")
    public void sendByUserId(Long userId) throws Exception {
        webSocketServer.SendMessage("测试消息", userId);
    }


    @ApiOperation(value = "测试支付宝回调")
    @RequestMapping("/testNotify")
    public String testNotify(@RequestBody Map<String, String> map) throws AlipayApiException {
        return notify(map);
    }


    @ApiOperation(value = "支付宝回调")
    @RequestMapping("/notify")
    public String notify(@RequestParam Map<String, String> map) throws AlipayApiException {
//    public String notify(@RequestBody Map<String, String> map) throws AlipayApiException {
        System.out.println("支付宝回调参数:" + JSON.toJSONString(map));
        String tradeStatus = map.get("trade_status");
        if (!StrUtil.equals("TRADE_SUCCESS", tradeStatus)) {
            return "success";
        }
        String orderNo = map.get("out_trade_no");
        Order order = new Order();
        order.setOrderNo(orderNo);

        order = orderService.getDomain(order);
        if (!StrUtil.equals(OrderStatusEnum.handling.getValue(), order.getOrderStatus())) {
            return null;
        }
        order.setOrderStatus(OrderStatusEnum.success.getValue());
        //更改订单状态
        orderService.updateOrder(order);
        //回调下游订单
        orderService.notifyAgent(order);
        return "success";
    }

    @ApiOperation(value = "上游系统回调", hidden = true)
    @RequestMapping("/notifyMe")
    public String notifyMe(@RequestBody ApiNotifyDto apiNotifyDto) throws AlipayApiException {
        return "success";
    }
    @ApiLog
    @ApiOperation(value = "创建代收链接订单")
    @PostMapping("/create")
    public ResponseResult create(@Valid @RequestBody ApiOrderReceiveAddDto apiBxOrderPayAddDto) {

        return this.setSuccessResult(orderService.apiOrder(apiBxOrderPayAddDto, ""));
    }

    @Resource
    RedisCache redisCache;

    @ApiOperation(value = "进入支付页面数据")
    @GetMapping("/pay")
    public ResponseResult<Bank> pay(PagePayVo apiPayResultVo) {
        // log.info("进入页面参数:{}", JSON.toJSONString(apiPayResultVo));
//        Map<String, Object> cacheObject = redisCache.getCacheObject("orderNo:" + apiPayResultVo.getOrderNo());
        Order order = this.orderService.getByOrderNo(apiPayResultVo.getOrderNo());
        if (order == null) {
            throw new BusiException("订单已关闭");
        }
        AliPayVo aliPayVo = BeanUtil.copyProperties(order, AliPayVo.class);
        aliPayVo.setQrCode(order.getZfbUrl());
        Map<String, Object> map = BeanUtil.beanToMap(aliPayVo);
        if (StrUtil.isBlank(order.getPayer())) {
            map.put("channelCode", order.getChannelCode());
        }
        map.put("channelName", order.getChannelName());
        map.put("name", order.getName());
        map.put("account", order.getAccount());
        map.put("html", order.getHtml());
        map.put("bankName", order.getBankName());
        map.put("zfbUserId", order.getZfbUserId());
        map.put("amount", order.getPayAmount());
        map.put("payName", order.getPayer());
        String s = configService.selectConfigByKey("payOrderExpire");
        DateTime dateTime = DateUtil.offsetMinute(order.getCreateTime(), StrUtil.isBlank(s) ? 5 : Integer.valueOf(s));
        map.put("merchantOrderNo", order.getMerchantOrderNo());
        long expireTime = (dateTime.getTime() - new Date().getTime()) / 1000;
        map.put("expireTime", expireTime);
        map.put("createTime", DateUtil.formatDateTime(order.getCreateTime()));
        return this.setSuccessResult(map);
    }


    @ApiOperation(value = "设置付款人")
    @PostMapping("/setPayer")
    public ResponseResult setPayer(@Valid @RequestBody OrderAddDto orderAddDto) {

        Order check = this.orderService.getByOrderNo(orderAddDto.getOrderNo());
        if (check == null) {
            throw new BusiException("订单已关闭");
        }
        check.setPayer(orderAddDto.getPayer());
        this.orderService.updateDomain(check);
        return ResponseResult.createBySuccess();
    }

    @ApiOperation(value = "设置付款人")
    @RequestMapping("/setPayer1")
    public ResponseResult setPayer1(OrderAddDto orderAddDto) {

        Order check = this.orderService.getByOrderNo(orderAddDto.getOrderNo());
        if (check == null) {
            throw new BusiException("订单已关闭");
        }
        check.setPayer(orderAddDto.getPayer());
        Order order=new Order();
        order.setId(check.getId());
        order.setPayer(orderAddDto.getPayer());
        this.orderService.updateDomain(order);
        return ResponseResult.createBySuccess();
    }

    @ApiOperation(value = "进入支付页面数据")
    @GetMapping("/getByOrderNo")
    public ResponseResult<Bank> getByOrderNo(PagePayVo apiPayResultVo) {
        //log.info("进入页面参数:{}", JSON.toJSONString(apiPayResultVo));
//        Map<String, Object> cacheObject = redisCache.getCacheObject("orderNo:" + apiPayResultVo.getOrderNo());
        Order order = this.orderService.getByOrderNo(apiPayResultVo.getOrderNo());
        if (order == null) {
            throw new BusiException("订单已关闭");
        }
        AliPayVo aliPayVo = BeanUtil.copyProperties(order, AliPayVo.class);
        aliPayVo.setQrCode(order.getZfbUrl());
        Map<String, Object> map = BeanUtil.beanToMap(aliPayVo);
        if (StrUtil.isBlank(order.getPayer())) {
            map.put("channelCode", order.getChannelCode());
        }
        map.put("channelName", order.getChannelName());
        map.put("amount", order.getPayAmount());
        map.put("name", order.getName());
        map.put("account", order.getAccount());
        map.put("html", order.getHtml());
        map.put("payer", order.getPayer());
        map.put("merchantOrderNo", order.getMerchantOrderNo());
        return this.setSuccessResult(order);
    }

    @Resource
    private GoodsService goodsService;

    @ApiOperation(value = "上传转账码")
    @PostMapping("/uploadPic")
    public ResponseResult uploadPic(MultipartFile file, String orderNo) throws Exception {
        Order order = this.orderService.getByOrderNo(orderNo);
        if (order == null) {
            throw new BusiException("订单不存在");
        }
        String filename = FileUploadUtils.extractFilename(file);
        String pic = AliOss.uploadToOss(file, "common/" + filename);
        Order domain = new Order();
        domain.setId(order.getId());
        domain.setPayerPic(pic);
//        上传图时间
        domain.setApiRemark(DateUtil.now());
        this.orderService.updateDomain(domain);
        return ResponseResult.createBySuccess(pic);
    }
}
